package com.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.order.dto.OrderDTO;
import com.order.dto.OrderDetailDTO;
import com.order.enums.OrderStatusEnum;
import com.order.enums.PayStatusEnum;
import com.order.enums.ResultEnum;
import com.order.exception.SellException;
import com.order.pojo.OrderDetail;
import com.order.pojo.OrderMaster;
import com.order.mapper.OrderMasterMapper;
import com.order.pojo.ProductCategory;
import com.order.pojo.ProductInfo;
import com.order.service.IOrderDetailService;
import com.order.service.IOrderMasterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.order.service.IProductInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cucu
 * @since 2025-08-11
 */
@Service
public class OrderMasterServiceImpl extends ServiceImpl<OrderMasterMapper, OrderMaster> implements IOrderMasterService {

    @Autowired
    OrderMasterMapper orderMasterMapper;

    @Autowired
    IOrderDetailService orderDetailService;

    @Autowired
    IProductInfoService productInfoService;

    @Override
    public PageInfo<OrderMaster> getOrderMasterByPage(Integer page, Integer size, OrderMaster orderMaster) {
        PageHelper.startPage(page, size);
        QueryWrapper<OrderMaster> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(true, "buyer_name", orderMaster.getBuyerName());
        queryWrapper.eq(true, "del", 0);
        List<OrderMaster> orderMasterList = orderMasterMapper.selectList(queryWrapper);
        return PageInfo.of(orderMasterList);
    }

    /**
     * 买家下单--事务操作！ @Transactional  事务注解
     *
     * @param orderDTO
     * @return
     */
    @Transactional
    @Override
    public OrderDTO createOrder(OrderDTO orderDTO) {
        // 雪花算法获取ID: 生产一个随时永远不重复的订单号
        String orderId = String.valueOf(IdUtil.getSnowflake().nextId());
        //  Decimal double 钱用 Decimal表示？
        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
        //1. 查询商品（数量, 价格）
        for (OrderDetail orderDetail : orderDTO.getOrderDetailList()) {
            //根据商品ID查询一下商品
            ProductInfo productInfo = productInfoService.getById(orderDetail.getProductId());
            if (productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            //2. 计算订单总价
            orderAmount = productInfo.getProductPrice().multiply(new BigDecimal(orderDetail.getProductQuantity())).add(orderAmount);
            //订单详情入库
            orderDetail.setDetailId(String.valueOf(IdUtil.simpleUUID()));
            orderDetail.setOrderId(orderId);
            BeanUtils.copyProperties(productInfo, orderDetail);
            //【新增订单详情order_detail】
            orderDetailService.save(orderDetail);
        }
        //3. 写入订单数据库（orderMaster和orderDetail）
        OrderMaster orderMaster = new OrderMaster();
        orderDTO.setOrderId(orderId);
        BeanUtils.copyProperties(orderDTO, orderMaster);
        orderMaster.setOrderAmount(orderAmount);

        orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
        orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
        //【新增订单详情order_master】
        orderMasterMapper.insert(orderMaster);
        //4. 扣库存
        List<OrderDetail> orderDetailList = orderDTO.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            String productId = orderDetail.getProductId();
            Integer productQuantity = orderDetail.getProductQuantity();
            ProductInfo productInfo = productInfoService.getById(productId);
            if (productInfo == null) {
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            //扣库存
            Integer result = productInfo.getProductStock() - productQuantity;
            if (result < 0) {
                //库存不足
                throw new SellException(ResultEnum.PRODUCT_STOCK_ERROR);
            }
            productInfo.setProductStock(result);
            //【更新商品的库存】
            productInfoService.updateById(productInfo);
        }
        orderDTO.setOrderId(orderId);
        return orderDTO;
    }

    @Transactional
    @Override
    public boolean cancelOrder(String orderId, String openid) {
        OrderMaster orderMaster = orderMasterMapper.selectById(orderId);
        if (orderMaster == null) {
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }
        if (Objects.equals(orderMaster.getPayStatus(), PayStatusEnum.SUCCESS.getCode())) {
            throw new SellException(ResultEnum.ORDER_PAY_STATUS_ERROR);
        }
        if (!Objects.equals(orderMaster.getBuyerOpenid(), openid)) {
            throw new SellException(ResultEnum.ORDER_OWNER_ERROR);
        }
        try {
            // 更新订单状态
            orderMaster.setOrderStatus(OrderStatusEnum.CANCEL.getCode());
            orderMaster.setPayStatus(PayStatusEnum.CLOSE.getCode());
            orderMaster.setUpdateTime(DateUtil.now());
            orderMasterMapper.updateById(orderMaster);
            // 返回库存
            List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper<OrderDetail>().eq("order_id", orderId));
            if (orderDetailList == null || orderDetailList.isEmpty()) {
                throw new SellException(ResultEnum.ORDERDETAIL_NOT_EXIST);
            }
            for (OrderDetail orderDetail : orderDetailList) {
                ProductInfo productInfo = productInfoService.getById(orderDetail.getProductId());
                if (productInfo == null) {
                    throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
                }
                // 增加库存
                Integer newStock = productInfo.getProductStock() + orderDetail.getProductQuantity();
                productInfo.setProductStock(newStock);
                // 更新商品库存
                productInfoService.updateById(productInfo);
            }
            return true;
        } catch (Exception e) {
            throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }
    }

    @Override
    public List<OrderDTO> getOrderList(String openid) {
        List<OrderMaster> orderMasterList = orderMasterMapper.selectList(new QueryWrapper<OrderMaster>().eq("del", 0).eq("buyer_openid", openid).orderByDesc("create_time"));
        List<OrderDTO> orderDTOList = new ArrayList<>();
        for (OrderMaster orderMaster : orderMasterList) {
            OrderDTO orderDTO = new OrderDTO();
            BeanUtils.copyProperties(orderMaster, orderDTO);
            orderDTOList.add(orderDTO);
        }
        return orderDTOList;
    }

    @Override
    public OrderDetailDTO getOrderDetail(String orderId, String openid) {
        OrderMaster orderMaster = orderMasterMapper.selectById(orderId);
        if (orderMaster == null) {
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }
        List<OrderDetail> orderDetailList = orderDetailService.list(new QueryWrapper<OrderDetail>().eq("order_id", orderId));
        if (orderDetailList == null || orderDetailList.isEmpty()) {
            throw new SellException(ResultEnum.ORDERDETAIL_NOT_EXIST);
        }
        if (!Objects.equals(orderMaster.getBuyerOpenid(), openid)) {
            throw new SellException(ResultEnum.ORDER_OWNER_ERROR);
        }
        OrderDetailDTO orderDTO = new OrderDetailDTO();
        BeanUtils.copyProperties(orderMaster, orderDTO);
        orderDTO.setOrderDetailList(orderDetailList);
        orderDTO.setCreateTime(DateUtil.parse(orderMaster.getCreateTime(), "yyyy-MM-dd HH:mm:ss").getTime() / 1000);
        orderDTO.setUpdateTime(DateUtil.parse(orderMaster.getUpdateTime(), "yyyy-MM-dd HH:mm:ss").getTime() / 1000);

        return orderDTO;
    }

    @Override
    public OrderDTO findOne(String orderId) {
        OrderMaster orderMaster = orderMasterMapper.selectById(orderId);
        OrderDTO orderDTO = new OrderDTO();
        BeanUtils.copyProperties(orderMaster, orderDTO);
        return orderDTO;
    }

    @Override
    public BigDecimal sumMoney() {
        List<OrderMaster> orderMasterList = orderMasterMapper.selectList(new QueryWrapper<OrderMaster>().eq("del", 0).eq("pay_status", PayStatusEnum.SUCCESS.getCode()));
        if (orderMasterList == null || orderMasterList.isEmpty()) {
            return new BigDecimal(BigInteger.ZERO);
        }
        BigDecimal total = new BigDecimal(BigInteger.ZERO);
        for (OrderMaster orderMaster : orderMasterList) {
            total = total.add(orderMaster.getOrderAmount());
        }
        return total;
    }


}
